package com.seelyn.rhea.mvc;

import com.seelyn.rhea.mvc.common.exception.RheaException;
import com.seelyn.rhea.mvc.common.utils.StringUtils;
import com.seelyn.rhea.mvc.context.Request;
import com.seelyn.rhea.mvc.context.Response;
import com.seelyn.rhea.mvc.internal.InternalRequest;
import com.seelyn.rhea.mvc.internal.InternalResponse;
import com.seelyn.rhea.mvc.internal.RheaDispatcher;
import com.seelyn.rhea.mvc.internal.RheaFactory;
import com.seelyn.rhea.mvc.plugin.PluginBuilder;
import com.seelyn.rhea.mvc.route.HttpDispatcher;
import com.seelyn.rhea.mvc.route.BuilderFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 *
 * @author slacrey
 * @since 2016/1/20
 */
public abstract class RheaMvcFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(RheaMvcFilter.class);
    private static final String ENCODING = "encoding";
    private static final String DEFAULT_ENCODING = "UTF-8";
    private String encoding;
    private final HttpDispatcher httpDispatcher = RheaDispatcher.getInstance();
    private final RheaFactory factory = RheaFactory.getInstance();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //获取编码方式,若没有设置则使用默认编码
        encoding = filterConfig.getInitParameter(ENCODING);
        if (StringUtils.isBlank(encoding)) {
            encoding = DEFAULT_ENCODING;
        }


        try {

            //初始化路由
            initRoutes(factory.builder());

            // 初始化错误处理器
            initResolvers(factory.builder());

            //初始化插件
            initPlugins(factory.plugin());


        } catch (RheaException e) {
            logger.error(e.getMessage(), e);
        }


        factory.startup();

    }

    protected abstract void initPlugins(PluginBuilder builder) throws RheaException;

    protected abstract void initRoutes(BuilderFactory builder) throws RheaException;

    protected abstract void initResolvers(BuilderFactory builder) throws RheaException;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        request.setCharacterEncoding(encoding);

        Request requestWrap = InternalRequest.build(request);
        Response responseWrap = InternalResponse.build(response);

        boolean isRouted = false;
        try {
            isRouted = httpDispatcher.dispatch(requestWrap, responseWrap);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        if (!isRouted) {
            filterChain.doFilter(servletRequest, servletResponse);
        }

    }

    @Override
    public void destroy() {
        factory.shutdown();
    }
}
